<!--
ModelDialog 是针对业务单表的新增、编辑、详情的方法，提供公共组件
-->
<template>
  <el-dialog ref="modelDialog" :title="title" v-if="dialogVisible" :visible.sync="dialogVisible" :width="modelWidth"
    :before-close="handleClose" :close-on-click-modal="false" :close-on-press-escape="false" :destroy-on-close="true"
    :lock-scroll="false" v-bind="$attrs" v-on="$listeners">
    <div class="min-body-height">
      <slot ref="modelDialogSlot" name="dialog-content" :dataId="dataId" :tableData="tableData"
        :operatorType="operatorType" :isLoadData="isLoadData" :loadDataUrl="loadDataUrl" :serviceParam="serviceParam" />
    </div>
    <!--zp 增加了业务参数-->
    <span v-if="isShowButton" slot="footer" class="dialog-footer">
      <el-button size="small" @click="closeDialog">取 消</el-button>
      <el-button size="small" :loading="loading" type="primary" @click="onsubmit" :disabled="ifDisabled">确 定</el-button>
    </span>
  </el-dialog>
</template>

<script>
import { postAction, putAction, uploadFile } from '@/utils/httpUtil';
export default {
  name: 'ModelDialog',
  props: {
    // 自定义成功提示信息
    customOkMsg: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      dialogVisible: false, // 是否打开
      operatorType: '',
      title: '操作',
      loading: false,
      dataId: '', // 在修改的时候需要传入dataId进行查询数据
      tableData: {}, // 在修改或者详细的时候传入的表格的数据
      serviceParam: {}, // zp 增加了业务参数
      url: '', // 在新增修改的时候需要进行提交的url
      ifDisabled: false, // 确定按钮disable默认false
      isLoadData: false, // 2020年4月15日14:31:12 增加了页面是否需要进行重新加载数据
      loadDataUrl: '', // 2020年4月15日14:37:32 增加了页面通过主键进行加载的数据的url
      isExistUpload: false,
      modelWidth: '60%'
    };
  },
  computed: {
    isShowButton: function () {
      if (this.serviceParam) {
        if (this.serviceParam.hiddenBtn) {
          return false
        }
      }
      return this.operatorType === '1' ? false : true
    }
  },
  methods: {
    /**
     * @description dialog的标题，是否显示底部的按钮
     * @param title 标题 isShowBtn是否显示底部的按钮
     */
    showDialogAdd(
      title,
      url,
      isExistUpload = false,
      width = '60%',
      serviceParam = {},
      tableData
    ) {
      this.title = title;
      this.dialogVisible = true;
      this.isExistUpload = isExistUpload;
      this.modelWidth = width;
      this.$nextTick(() => {
        if (tableData) {
          this.tableData = { ...tableData };
        }
        this.operatorType = '0';
        this.dataId = '';
        this.url = url;
        this.isLoadData = false;
        this.loadDataUrl = '';
        this.serviceParam = serviceParam;
      });
    },
    showDialogInfo(
      title,
      tableData,
      isExistUpload = false,
      width = '60%',
      isLoadData = false,
      loadDataUrl = '',
      serviceParam = {}
    ) {
      this.title = title;
      this.dialogVisible = true;
      this.modelWidth = width;
      this.$nextTick(() => {
        if (tableData) {
          this.tableData = { ...tableData };
          this.dataId = tableData.id;
        }
        this.operatorType = '1';
        this.isLoadData = isLoadData;
        this.loadDataUrl = loadDataUrl;
        this.serviceParam = serviceParam;
      });
    },
    showDialogEdit(
      title,
      tableData,
      url,
      isExistUpload = false,
      width = '60%',
      isLoadData = false,
      loadDataUrl = '',
      serviceParam = {}
    ) {
      this.title = title;
      this.dialogVisible = true;
      this.modelWidth = width;
      this.isExistUpload = isExistUpload;
      this.$nextTick(() => {
        if (tableData) {
          this.tableData = { ...tableData };
          this.dataId = tableData.id;
        }
        this.operatorType = '2';
        this.url = url;
        this.isLoadData = isLoadData;
        this.loadDataUrl = loadDataUrl;
        this.serviceParam = serviceParam;
      });
    },
    // 处理dialog的关闭的回调
    handleClose(done) {
      this.closeDialog();
    },
    closeDialog() {
      const childModel = this.getChildModel();
      if (childModel && childModel.$refs.modelForm) {
        childModel.$refs.modelForm.resetFields();
        // 增加了弹框的回调
        childModel.closeDialogCallback();
      }
      this.loading = false;
      this.dataId = '';
      this.operatorType = '';
      this.dialogVisible = false;
      this.isLoadData = false;
      this.loadDataUrl = '';
      this.serviceParam = {};
      this.$emit('cancel');
    },
    // 获取子组件的方法
    getChildModel: function () {
      const dialogChilds = this.$refs.modelDialog.$children;
      return dialogChilds.find((item, index, array) => item.$refs.modelForm);
    },
    // 业务提交的方法
    onsubmit: function () {
      /**
       * zp 2019年10月22日11:11:26 根据child进行获取子组件的属性和方法 后续优化
       * @description
       * 1.在通用的弹框中进行提交各个模块的edit 和 add 方法
       * 2.在各个模块中的form的ref 都改成modelForm,
       * 3.在各个模块中只需要写对应的form item、验证规则、及其其他的业务代码比如：需要展示角色的数据等
       *
       * */
      const childModel = this.getChildModel();
      this.ifDisabled = true;
      this.loading = true;
      childModel.$refs.modelForm.validate(valid => {
        if (valid) {
          /**
           * 提交之前回调函数，子组件定义beforeSubmit方法，提交之前自定义验证。验证通过返回true。不通过返回false
           * beforeSubmit() {
           *    // 自定义验证内容
           *    return true或者false
           * }
           */
          const beforeSubmitValidate = this.beforeSubmit();
          if (!beforeSubmitValidate) {
            this.loading = false;
            this.ifDisabled = false;
            return;
          }
          //let modelFrom = childModel.modelForm;
          let modelFrom = childModel.saveBeforeGetModelForm();
          if (!this.url) {
            this.$message.warning('保存或者编辑的url为空！请检查代码');
            this.loading = false;
          } else {
            let returnPromis;
            let headers;
            if (this.isExistUpload) {
              headers = {
                'Content-Type': 'multipart/form-data'
              };
              let formData = new FormData();
              for (let key in modelFrom) {
                if (
                  modelFrom[key] != null &&
                  modelFrom[key] !== undefined &&
                  modelFrom[key] !== ''
                ) {
                  if (key.lastIndexOf('TextValue') <= 0) {
                    formData.append(key, modelFrom[key]);
                  }
                }
              }
              modelFrom = formData;
            } else {
              for (let key in modelFrom) {
                if (
                  modelFrom[key] != null &&
                  modelFrom[key] !== undefined &&
                  modelFrom[key] !== ''
                ) {
                  if (key.lastIndexOf('TextValue') >= 0) {
                    delete modelFrom[key];
                  }
                }
              }
            }
            if (this.dataId) {
              returnPromis = putAction(this.url, modelFrom, headers);
            } else {
              returnPromis = postAction(this.url, modelFrom, headers);
            }
            returnPromis
              .then(res => {
                if (res.success) {
                  if (!this.customOkMsg) {
                    this.$message.success(res.message);
                  }
                  this.dataId = '';
                  this.$emit('ok', res);
                  this.closeDialog();
                }
                // 20211011 yangxuemei 修改多次重复弹消息框问题，这里直接注释掉就行
                //  else {
                //   this.$message.warning(res.msg);
                // }
              })
              .finally(() => {
                this.loading = false;
                this.ifDisabled = false;
              });
          }
        } else {
          this.loading = false;
          this.ifDisabled = false;
        }
      });
    },
    /**
     * 调用弹窗内部组件方法beforeSubmit（）
     */
    beforeSubmit() {
      const dialogChilds = this.$refs.modelDialog.$children;
      let func = true;
      if (dialogChilds) {
        for (let index = 0; index < dialogChilds.length; index++) {
          let item = dialogChilds[index];
          if (item.beforeSubmit) {
            func = item.beforeSubmit();
            break;
          }
        }
      }
      return func;
    }
  }
}
</script>

<style lang="scss" scoped>
/*/deep/.el-dialog {*/
/*  margin-top: 10vh !important;*/
/*  height: 80vh;*/
/*  overflow: auto;*/
/*  margin-bottom: 10vh;*/
/*}*/
</style>